<!--
 * @Date: 2023-02-22 11:01:47
 * @LastEditors: Zireael 1193875164@qq.com
 * @LastEditTime: 2023-03-19 09:20:47
 * @FilePath: \A19\frontend\src\components\Regist.vue
-->
<template>
  <div class="container">
    <div class="header"><span id="title">注册</span></div>
    <div class="body">
      <el-form ref="theForm" :model="signForm" label-width="80px" :rules="signRules" size="large">
        <el-form-item label="头像" prop="portrait" error="">
          <el-upload
            class="user-portrait"
            action="#"
            :on-change="selected"
            :show-file-list="false"
            :http-request="async () => {}"
          >
            <img :src="signForm.portrait.fileDate" class="avatar" />
            <el-icon><Picture /></el-icon>
            <!-- <i class="el-icon-picture-outline"></i> -->
          </el-upload>
        </el-form-item>
        <el-form-item label="用户名" prop="username">
          <el-input v-model="signForm.username"></el-input>
        </el-form-item>
        <el-form-item label="" prop="role">
          <el-radio v-model="signForm.role" label="teacher"
            >我是教师</el-radio>
          <el-radio v-model="signForm.role" label="student"
            >我是学生</el-radio>
        </el-form-item>
        <el-form-item label="性 别" prop="gender">
          <el-radio v-model="signForm.gender" :label="Gender.male"
            ><el-icon><Male /></el-icon
          ></el-radio>
          <el-radio v-model="signForm.gender" :label="Gender.female"
            ><el-icon><Female /></el-icon
          ></el-radio>
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input type="password" v-model="signForm.password"></el-input>
        </el-form-item>
        <el-form-item label="确认密码" prop="reinput">
          <el-input type="password" v-model="signForm.reinput"></el-input>
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="signForm.email"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" plain @click="send" :disabled="counting">{{
            counting ? `(${count})重新获取` : "获取验证码"
          }}</el-button>
        </el-form-item>
        <el-form-item label="验证码" prop="test">
          <el-input v-model="signForm.test"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" size="large" @click="sign" 
            >注册</el-button
          >
          <el-button size="large" @click="disSign">取 消</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, reactive, computed } from "vue";
import type { FormInstance, FormRules, UploadRequestHandler,UploadFile } from "element-plus";
import { Gender } from "@/utils/Gender";
import { useClientStore } from '../pinia/stores/client';
import { ValidateFieldsError } from "async-validator";
import { conf } from '../utils/conf';
import {ReqRegist} from '@/shared/protocols/Login/PtlRegist'
import router from "@/route";

const client = useClientStore().client

const theForm = ref<FormInstance>()
const signForm = reactive({
  portrait:{
    fileDate: /*base64*/ conf.server + '/User.ico' ,
    fileType: undefined as undefined | string,
    fileUploadDate:new Uint8Array()
  },
  username: "",
  role:'teacher',
  gender: Gender.male,
  password: "",
  reinput: "",
  email: "",
  test: "",
});
const code = ref('')

const signRules = reactive({
  portrait: [],
  username: [{ required: true, message: "请输入用户名", trigger: "blur" }],
  password: [
    { required: true, message: "请输入密码", trigger: "blur" },
    {
      min: 6,
      max: 16,
      message: "长度在 6 到 16 个字符",
      trigger: "blur",
    },
  ],
  reinput:[
    {
        required:true,message:'再次输入密码',trigger:"change",
    },{
        validator:(rule,value:string,callback)=>{
            if(value === signForm.password){
                return callback()
            }
            else{
                return callback(new Error())
            }
        },
        message:'两次的密码不一致'
    }
  ],
  email:[
    { required: true, message: "请输入邮箱地址", trigger: "blur" },
    {
        type:'email',
        message:'请输入正确的邮箱地址',
        trigger: ["blur", "change"],
    }
  ],
  test: [
    { required: true, message: "请输入验证码", trigger: "change" },
    {
        validator:(rule,value:string,callback)=>{
            if(code.value){
                if(code.value === signForm.test){
                    return callback()
                }
                else{
                    return callback(new Error)
                }
            }else{
                return callback(new Error)
            }
        },
        message:'验证码错误'
    }
],
} as FormRules);
let counter:NodeJS.Timer
const counting = ref(false);
const count = ref(0);
const send = async () => {
    if(!signForm.email) return ElMessage.warning('请输入邮箱')
    const res = await client.callApi('Login/TestEmail',{
        email:signForm.email
    })
    count.value = 59
    counting.value = true
    if(res.isSucc){
        counter = setInterval(()=>{
            if(count.value === 0){
                clearInterval(counter)
                counting.value = false
            }
            else{
                count.value--
            }
        },1000)
        code.value = res.res.code
    }

};
const selected = ({raw,status}: UploadFile) => {
    if(status !== 'success') return
    if(raw === undefined) return
    if (raw.type !== 'image/jpeg' && raw.type !== 'image/png') {
        ElMessage.error('上传头像图片只能是 JPG 或 PNG 格式!')
        return 
    } else if (raw.size / 1024 / 1024 > 2) {
        ElMessage.error('上传头像图片大小不能超过 2MB!')
        return 
    }
    
    signForm.portrait.fileType = raw.type
    const reader1 = new FileReader()
    const reader2 = new FileReader()
    reader1.addEventListener('load',() =>{
        signForm.portrait.fileDate = reader1.result as string
    })
    reader1.readAsDataURL(raw)
    reader2.addEventListener('load',() =>{
        signForm.portrait.fileUploadDate = new Uint8Array(reader2.result as ArrayBuffer)
    })
    reader2.readAsArrayBuffer(raw)
};
const disSign = () => {};
const sign = async () => {
    // if(!code.value || signForm.test !== code.value ) return ElMessage.warning('验证码不正确')
    try {
        const res = await theForm.value!.validate()
        if(res){
            const regist:ReqRegist = {
                portrait:signForm.portrait.fileType?{
                    fileDate:signForm.portrait.fileUploadDate,
                    fileType:signForm.portrait.fileType
                }:undefined,
                role: signForm.role,
                name: signForm.username,
                gender: signForm.gender,
                email: signForm.email,
                password: signForm.password
            }
            const ret = await client.callApi('Login/Regist',regist)
            if(ret.isSucc){
                ElMessage.success('注册成功')
                router.replace({name:'login'})
            }
        }
    } catch (error) {
        (error as ValidateFieldsError)
    }
};
</script>

<style lang="less" scoped>
.container {
  width: 35%;
  position: absolute;
  top: 3vh;
  /* bottom: 0; */
  left: 0;
  right: 0;
  margin: 0 auto;
  height: auto;
  background-color: white;
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  padding-top:0;
  .header {
    padding: 20px;
    padding-bottom: 10px;
    #title {
      line-height: 24px;
      font-size: 18px;
      color: #303133;
    }
  }
  .body {
    padding: 10px 20px;
    color: #606266;
    font-size: 14px;
    word-break: break-all;
    .user-portrait {
      position: relative;
      font-size: 14px;
      box-sizing: border-box;
      outline: none;
      vertical-align: middle;
      border: 0;
      margin: 0;
      padding: 0;
      height: 100px;
      width: 100px;
      border-radius: 50%;
      overflow: hidden;
      i {
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        margin: auto;
        height: 50px;
        width: 50px;
        text-align: center;
        line-height: 50px;
        font-size: 35px;
        color: #fff;
        opacity: 0;
        transition: opacity 0.3s ease;
      }
      img {
        height: 100px;
        width: 100px;
        display: block;
        transition: filter 0.3s ease;
      }
      &:hover {
        img {
          filter: brightness(0.8);
        }
        i {
          opacity: 0.9;
        }
      }
    }
  }
}
</style>
